<?php

namespace App\Http\Controllers\Api;

use App\Http\Requests\Api\ForgetPasswordRequest;
use App\Http\Requests\Api\UpdatePayPasswordRequest;
use App\Http\Requests\Api\UserDataRequest;
use App\Http\Requests\Api\UsersRequest;
use App\Http\Requests\Api\UpdatePasswordRequest;
use App\Models\Shop;
use App\Models\UserData;
use App\Models\Wallet;
use App\Services\EmailService;
use App\Transformers\UserTransformer;
use App\Models\User;
use Illuminate\Support\Facades\DB;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Auth;

class AuthorizationController extends Controller
{
    /**
     * Create a new AuthController instance.
     *
     * @return void
     */
    public function __construct()
    {

    }

    /**
     * 用户登录
     *
     * @param Request $request
     * @return \Dingo\Api\Http\Response|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
     */
    public function login(Request $request)
    {
        $username = $request->input('username');
        $password = $request->input('password');

        $user = User::where('username', $username)->first();

        if (!$user || !Hash::check($password, $user->password)) {
            return response(['message' => trans('api.account_or_password_error'), 'code' => 0, 'status' => false]);
        }

        if ($user->login_status == User::FORBIDDEN) {
            return response(['message' => trans('api.forbidden'), 'code' => 1, 'status' => false]);
        }

        $token = Auth::guard('api')->fromUser($user);

        return $this->respondUserWithToken($token, $user);
    }

    /**
     * 用户信息
     *
     * @return \Dingo\Api\Http\Response
     */
    public function me()
    {
        return $this->response->item(auth()->user(), new UserTransformer());
    }

    /**
     * Log the user out (Invalidate the token).
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function logout()
    {
        Auth::guard('api')->logout();

        return response()->json(['message' => '退出成功', 'code' => 1, 'status' => true, 'data' => '']);
    }

    /**
     * Refresh a token.
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function refresh()
    {
        $user = User::find($this->user['id']);

        $token = Auth::guard('api')->refresh();

        return $this->respondUserWithToken($token, $user);
    }

    /**
     * Get the token array structure.
     *
     * @param  string $token
     *
     * @return \Illuminate\Http\JsonResponse
     */
    protected function respondWithToken($token)
    {
        return response()->json([
            'access_token' => $token,
            'token_type' => 'bearer',
            'expires_in' => auth()->factory()->getTTL() * 60,
        ]);
    }

    protected function respondUserWithToken($token, $user)
    {
        return $this->response->item($user, new UserTransformer())
            ->setMeta([
                'access_token' => $token,
                'token_type' => 'Bearer',
                'expires_in' => Auth::guard('api')->factory()->getTTL(),
            ])
            ->setStatusCode(200);
    }

    /**
     * 注册
     *
     * @param UsersRequest $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function store(UsersRequest $request)
    {

        $user = $request->only([
            'nick_name', 'avatar', 'email', 'password', 'role', 'phone',
        ]);

        $user_data = $request->only([
            'age', 'stature', 'weight', 'bust', 'waist', 'hips', 'intro', 'video', 'video_cover',
        ]);

        $shop = $request->only(['province', 'city', 'district', 'begin_business_hours', 'end_business_hours', 'begin_free_time', 'end_free_time']);

        $user['username'] = $user['email'];
        $user['password'] = bcrypt($user['password']);

        $shop['face_picture'] = $user['avatar'];
        $shop['name'] = $user['nick_name'];

        DB::transaction(function () use ($user, $user_data, $shop) {
            try {
                $user = User::create($user);

                if ($user->role == User::SELLER) {
                    UserData::updateOrCreate(
                        ['user_id' => $user->id],
                        $user_data
                    );

                    Shop::updateOrCreate(
                        ['user_id' => $user->id],
                        $shop
                    );
                }
            } catch ( \Exception $exception ) {
                $this->response->error(trans('api.register_failed'), 200);
            }
        });

        return response()->json(['message' => trans('api.register_succeed'), 'code' => 1, 'status' => true, 'data' => '']);
    }

    /**
     * 修改个人资料
     *
     * @param UsersRequest $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function update(UsersRequest $request)
    {
        $user = $request->only([
            'nick_name', 'avatar', 'phone',
        ]);

        $user_data = $request->only([
            'age', 'stature', 'weight', 'bust', 'waist', 'hips', 'video', 'video_cover',
        ]);

        $shop = $request->only(['province', 'city', 'district', 'begin_business_hours', 'end_business_hours', 'begin_free_time', 'end_free_time']);

        DB::transaction(function () use ($user, $user_data, $shop) {
            try {
                User::where('id', $this->user->id)->update($user);

                if ($this->user->role == User::SELLER) {
                    UserData::where('user_id', $this->user->id)->update($user_data);

                    Shop::where('user_id', $this->user->id)->update($shop);
                }
            } catch
            ( \Exception $exception ) {
                $this->response->error(trans('api.update_failed'), 200);
            }
        });

        return response()->json(['message' => trans('api.update_succeed'), 'code' => 1, 'status' => true, 'data' => '']);
    }

    /**
     * 修改支付密码
     *
     * @param UpdatePasswordRequest $request
     * @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\JsonResponse|\Illuminate\Http\Response
     */
    public function changePayPassword(UpdatePasswordRequest $request)
    {
        $old_password = $request->get('password');

        $password = bcrypt($request->get('password'));

        //判断旧密码是否正确
        if (!Hash::check($old_password, $this->user->password)) {
            return response(['message' => trans('api.password_error'), 'code' => 0, 'status' => false]);
        }

        $res = $this->user->wallet->update(['pay_password' => $password]);

        if ($res) {
            return response()->json(['message' => trans('api.update_succeed'), 'code' => 1, 'status' => true, 'data' => ''], 200);
        } else {
            return response()->json(['message' => trans('api.update_failed'), 'code' => 0, 'status' => false], 200);
        }
    }

    /**
     * 修改登录密码
     *
     * @param UpdatePasswordRequest $request
     * @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\JsonResponse|\Illuminate\Http\Response
     */
    public function changePassword(UpdatePasswordRequest $request)
    {
        $old_password = $request->get('old_password');

        $password = bcrypt($request->get('password'));

        //判断旧密码是否正确
        if (!Hash::check($old_password, $this->user->password)) {
            return response(['message' => trans('api.password_error'), 'code' => 0, 'status' => false]);
        }

        $res = $this->user->update(['password' => $password]);

        if ($res) {
            return response()->json(['message' => trans('api.update_succeed'), 'code' => 1, 'status' => true, 'data' => ''], 200);
        } else {
            return response()->json(['message' => trans('api.update_failed'), 'code' => 0, 'status' => false], 200);
        }
    }

    /**
     * 忘记密码
     *
     * @param ForgetPasswordRequest $request
     * @return \Illuminate\Http\JsonResponse
     * @throws \App\Exceptions\ApiException
     */
    public function forgetPassword(ForgetPasswordRequest $request)
    {
        $email = $request->get('email');

        $password = bcrypt($request->get('password'));

        //验证邮箱...
        $verification_code = $request->get('verification_code');

        $service = new EmailService();

        $service->verify($email, $verification_code);

        $res = User::where('email', $email)->update(['password' => $password]);

        if ($res) {
            return response()->json(['message' => trans('api.update_succeed'), 'code' => 1, 'status' => true, 'data' => ''], 200);
        } else {
            return response()->json(['message' => trans('api.update_failed'), 'code' => 0, 'status' => false], 200);
        }
    }

    /**
     * 忘记支付密码
     *
     * @param ForgetPasswordRequest $request
     * @return \Illuminate\Http\JsonResponse
     * @throws \App\Exceptions\ApiException
     */
    public function forgetPayPassword(ForgetPasswordRequest $request)
    {
        $email = $request->get('email');

        $password = bcrypt($request->get('password'));

        //验证邮箱...
        $verification_code = $request->get('verification_code');

        $service = new EmailService();

        $service->verify($email, $verification_code);

        $user = User::where('email', $email)->first();

        $res = $user->wallet->update(['pay_password' => $password]);

        if ($res) {
            return response()->json(['message' => trans('api.update_succeed'), 'code' => 1, 'status' => true, 'data' => ''], 200);
        } else {
            return response()->json(['message' => trans('api.update_failed'), 'code' => 0, 'status' => false], 200);
        }
    }
}
